﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Web;

namespace blackhouse.Payments.Data {
    public abstract class AdoPaymentsDataAccess : IPaymentsDataAccess {

        #region I Members

        public PaymentTypeData GetPaymentType(string paymentKey) {
            return this.ReadPaymentType(this.GetPaymentTypeReader(paymentKey));
        }

        public PaymentTransactionStatusData GetPaymentTransactionStatus(int statusId) {
            return this.ReadPaymentTransactionStatus(this.GetPaymentTransactionStatusReader(statusId));
        }

        public PaymentTransactionData FindPaymentTransaction(int posId, string transactionSession) {
            return this.ReadPaymentTransaction(this.FindPaymentTransactionReader(posId, transactionSession));
        }

        public PaymentTransactionData GetPaymentTransaction(int paymentTransactionId) {
            return this.ReadPaymentTransaction(this.GetPaymentTransactionReader(paymentTransactionId));
        }

        public PaymentErrorData GetPaymentError(int errorId) {
            return this.ReadPaymentError(this.GetPaymentErrorReader(errorId));
        }

        public PaymentTransactionData GetPaymentTransactionByOrderId(int orderId) {
            return this.ReadPaymentTransaction(this.GetPaymentTransactionByOrderIdReader(orderId));
        }

        #endregion

        #region I Abstract Members

        public abstract int SaveNewPaymentTransaction(PaymentTransactionData data);
        public abstract void AddPaymentTransactionErrorLog(int transactionId, int errorId);
        public abstract void AddPaymentTransactionPositiveLog(int transactionId);
        public abstract int AddPaymentTransactionLog(int transactionId, PaymentTransactionData data);
        public abstract void SavePaymentTransaction(int transactionId, PaymentTransactionData data);
        public abstract void SavePaymentTransactionUpdateSnapshot(int paymentTransactionId, string snapshot);

        #endregion

        #region Abstract GetReader

        protected abstract IDataReader GetPaymentTypeReader(string paymentKey);
        protected abstract IDataReader GetPaymentTransactionStatusReader(int statusId);
        protected abstract IDataReader FindPaymentTransactionReader(int posId, string transactionSession);
        protected abstract IDataReader GetPaymentTransactionReader(int paymentTransactionId);
        protected abstract IDataReader GetPaymentErrorReader(int errorId);
        protected abstract IDataReader GetPaymentTransactionByOrderIdReader(int orderId);

        #endregion

        #region Read Collection Methods

        #endregion

        #region Read Single Methods

        private PaymentTypeData ReadPaymentType(IDataReader reader) {
            PaymentTypeData data = default(PaymentTypeData);
            if (reader.Read())
                data = this.ReadPaymentTypeFields(reader);
            reader.Close();
            return data;
        }

        private PaymentTransactionStatusData ReadPaymentTransactionStatus(IDataReader reader) {
            PaymentTransactionStatusData data = default(PaymentTransactionStatusData);
            if (reader.Read())
                data = this.ReadPaymentTransactionStatusFields(reader);
            reader.Close();
            return data;
        }

        private PaymentTransactionData ReadPaymentTransaction(IDataReader reader) {
            PaymentTransactionData data = default(PaymentTransactionData);
            if (reader.Read())
                data = this.ReadPaymentTransactionFields(reader);
            reader.Close();
            return data;
        }

        private PaymentErrorData ReadPaymentError(IDataReader reader) {
            PaymentErrorData data = default(PaymentErrorData);
            if (reader.Read())
                data = this.ReadPaymentErrorFields(reader);
            reader.Close();
            return data;
        }

        #endregion

        #region Read Fields Methods

        private PaymentTypeData ReadPaymentTypeFields(IDataReader reader) {
            PaymentTypeData data = new PaymentTypeData();
            data.PaymentKey = Convert.ToString(reader["PaymentKey"]);
            data.MinimumChargeValue = Convert.ToDouble(reader["MinimumChargeValue"]);
            data.MaximumChargeValue = Convert.ToDouble(reader["MaximumChargeValue"]);
            data.AutoCancelDays = Convert.ToInt32(reader["AutoCancelDays"]);
            data.Description = Convert.ToString(reader["Description"]);
            return data;
        }

        private PaymentTransactionStatusData ReadPaymentTransactionStatusFields(IDataReader reader) {
            PaymentTransactionStatusData data = new PaymentTransactionStatusData();
            data.StatusId = Convert.ToInt32(reader["StatusId"]);
            data.Description = Convert.ToString(reader["Description"]);
            return data;
        }

        private PaymentTransactionData ReadPaymentTransactionFields(IDataReader reader) {
            PaymentTransactionData data = new PaymentTransactionData();
            data.TransactionId = Convert.ToInt32(reader["TransactionId"]);
            data.PosId = Convert.ToInt32(reader["PosId"]);
            data.PosAuthKey = Convert.ToString(reader["PosAuthKey"]);
            data.PaymentType = Convert.ToString(reader["PaymentType"]);
            data.ChargeValue = Convert.ToDouble(reader["ChargeValue"]);
            data.Description = Convert.ToString(reader["Description"]);
            data.UserSessionId = Convert.ToString(reader["SessionId"]);
            data.FirstName = Convert.ToString(reader["FirstName"]);
            data.LastName = Convert.ToString(reader["LastName"]);
            data.EMail = Convert.ToString(reader["EMail"]);
            data.ClientIP = Convert.ToString(reader["ClientIP"]);
            data.Status = Convert.ToInt32(reader["Status"]);
            if (!reader.IsDBNull(reader.GetOrdinal("OrderID")))
                data.OrderID = Convert.ToInt32(reader["OrderID"]);
            if (!reader.IsDBNull(reader.GetOrdinal("Description2")))
                data.Description2 = Convert.ToString(reader["Description2"]);
            if (!reader.IsDBNull(reader.GetOrdinal("DescriptionBank")))
                data.DescriptionBank = Convert.ToString(reader["DescriptionBank"]);
            if (!reader.IsDBNull(reader.GetOrdinal("Street")))
                data.Street = Convert.ToString(reader["Street"]);
            if (!reader.IsDBNull(reader.GetOrdinal("StreetNumber")))
                data.StreetNumber = Convert.ToString(reader["StreetNumber"]);
            if (!reader.IsDBNull(reader.GetOrdinal("FlatNumber")))
                data.FlatNumber = Convert.ToString(reader["FlatNumber"]);
            if (!reader.IsDBNull(reader.GetOrdinal("City")))
                data.City = Convert.ToString(reader["City"]);
            if (!reader.IsDBNull(reader.GetOrdinal("PostCode")))
                data.PostCode = Convert.ToString(reader["PostCode"]);
            if (!reader.IsDBNull(reader.GetOrdinal("Country")))
                data.Country = Convert.ToString(reader["Country"]);
            if (!reader.IsDBNull(reader.GetOrdinal("Phone")))
                data.Phone = Convert.ToString(reader["Phone"]);
            if (!reader.IsDBNull(reader.GetOrdinal("Language")))
                data.Language = Convert.ToString(reader["Language"]);
            if (!reader.IsDBNull(reader.GetOrdinal("JavaScript")))
                data.JavaScript = Convert.ToBoolean(reader["JavaScript"]);
            if (!reader.IsDBNull(reader.GetOrdinal("PaybackLogin")))
                data.PaybackLogin = Convert.ToString(reader["PaybackLogin"]);
            if (!reader.IsDBNull(reader.GetOrdinal("Sig")))
                data.Sig = Convert.ToString(reader["Sig"]);
            if (!reader.IsDBNull(reader.GetOrdinal("Ts")))
                data.Ts = Convert.ToString(reader["Ts"]);
            if (!reader.IsDBNull(reader.GetOrdinal("CreatedDate")))
                data.CreatedDate = Convert.ToDateTime(reader["CreatedDate"]);
            if (!reader.IsDBNull(reader.GetOrdinal("BeginDate")))
                data.BeginDate = Convert.ToDateTime(reader["BeginDate"]);
            if (!reader.IsDBNull(reader.GetOrdinal("SentDate")))
                data.SentDate = Convert.ToDateTime(reader["SentDate"]);
            if (!reader.IsDBNull(reader.GetOrdinal("ReceiveDate")))
                data.ReceiveDate = Convert.ToDateTime(reader["ReceiveDate"]);
            if (!reader.IsDBNull(reader.GetOrdinal("CancelDate")))
                data.CancelDate = Convert.ToDateTime(reader["CancelDate"]);

            return data;
        }

        private PaymentErrorData ReadPaymentErrorFields(IDataReader reader) {
            PaymentErrorData data = new PaymentErrorData();
            data.ErrorId = Convert.ToInt32(reader["ErrorId"]);
            data.ErrorDescription = Convert.ToString(reader["ErrorDescription"]);
            return data;
        }

        #endregion

    }
}